package enemies;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import javax.swing.ImageIcon;

import towers.Tower;
import core.Model;
import core.ShootingUnit;
import core.Vector;

public abstract class Enemy extends ShootingUnit {
	
	protected Tower aimAtTower;
	protected int speed;
	protected Vector direction;
	protected int nextDestination = 0;
	protected double damageMultiplier;
	
	protected ArrayList<Point2D.Double> route;
	
	public Enemy( ArrayList<Point2D.Double> route, Point2D.Double position, int health, Dimension size, ImageIcon image, int firerate, int range, int speed, int damageMultiplier ) {
		super( position, health, image, size, 0, range, firerate );
		
		this.route = route;
		this.speed = speed;
		this.damageMultiplier = damageMultiplier;
	}
	
	public Tower getTower(){
		return aimAtTower;
	}
	
	public double getDamageMultiplier()
	{
		return damageMultiplier;
	}
	
	/**
	 * Definieer de tower waarop de enemy zal richten
	 * @param target
	 */
	public void setTower(Tower target){
		aimAtTower = target;
	}

	/**
	 * @return the speed
	 */
	public int getSpeed() {
		return speed;
	}
	/**
	 * @param speed the speed to set
	 */
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	
	public boolean update(){
		if(fireStorm){
			setPosition( new Point2D.Double( this.position.x + ( direction.x * speed), this.position.y + ( direction.y * speed)  ));
			return super.update();
		}
		
		// Is de tower al kapot?
		if ( aimAtTower != null && aimAtTower.getHealth() <= 0 )
			aimAtTower = null;
		
		// Enemy beweegt naar bestemming
		if ( nextDestination < route.size())
		{
			double deltaSpeed = this.speed * Model.timerInterval;
			
			if( deltaSpeed != 1 ) { // Alleen positie veranderen als het veranderd :P
			
				// Volgende punt ophalen, wat ook bestemming is
				Point2D.Double dest = route.get(nextDestination); 
				
				// Bereken richting
				this.direction = new Vector( dest.x - position.x, dest.y - position.y ).normalize();
				
				// Beweeg naar bestemming
				setPosition( new Point2D.Double( this.position.x + ( direction.x * deltaSpeed), this.position.y + ( direction.y * deltaSpeed)  ));
				
				// Viewangle aanpassen, moet wijzen naar bestemming
				
				double x = dest.x-position.x;
				double y = dest.y-position.y;
				//punt links van enemy
				if( x < 0 ){
					//punt hoger dan enemy
					x *= -1;
					if( y < 0 ){
						y *= -1;
						viewAngle = (int)Math.toDegrees( (Math.atan( ( y/x )   )) ) + 90 ;
					}
					//punt lager dan enemy
					else if( y >= 0 ){
						viewAngle = (int)Math.toDegrees( (Math.atan( ( x/y )   )) );
					}
				//punt rechts van enemy
				} else if( x >= 0 ){
					if( y < 0 ){
						y *= -1;
						viewAngle = (int)Math.toDegrees( (Math.atan( ( x/y )   )  ) )+ 180;
					} else if( y >= 0 ){
						viewAngle = (int)Math.toDegrees( (Math.atan( ( y/x  )   ))   )+ 270;
					}
				}
				
				
				// Papa update bounds
				super.update();
				
				// Zijn we aangekomen op de bestemming? Naar de volgende!
				// Kijk of we erg dichtbij zijn aangezien het niet altijd zeker is dat de vijand precies de bestemming bereikt
				if ( Math.abs(dest.x - position.x) < 3 && Math.abs( dest.y - position.y) < 3 )
					nextDestination++;
				
				return true;
			}
		}
		return false;
	}

	/**
	 * Geeft een Tower-object terug waarop de enemy richt
	 * @return Tower
	 */
	public Tower getAimAtTower() {
		return aimAtTower;
	}

	public Vector getDirection() {
		return direction;
	}
	
	public void moveObjectFireStorm(){
		super.moveObjectFireStorm();
		this.speed = 1;//(int)(Math.random() * 2);
		this.direction = new Vector((Math.random() * 40 -20), (Math.random() * 40-20));
	}
	
	public boolean isOnRoad()
	{
		return nextDestination > 0;
	}
	
	public void draw(Graphics g, Rectangle area, Component c ) {
		if ( isOutsideView() || nextDestination == 0 )
			return;
		
		super.draw(g, area, c);
	}
	
	
}
